;; https://projecteuler.net/problem=2

;; Even Fibonacci numbers

;; Problem 2

;; Each new term in the Fibonacci sequence is generated by
;; adding the previous two terms.  By starting with 1 and 2,
;; the first 10 terms will be:

;; 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

;; By considering the terms in the Fibonacci sequence whose
;; values do not exceed four million, find the sum of the
;; even-valued terms.



(import
  (except (rnrs base) let-values)
  (only (guile)
        ;; lambda forms
        lambda* λ
        command-line)
  (srfi srfi-1))


(define sum
  (λ (nums)
    (reduce + 0 nums)))


(define even?
  (λ (num)
    (= (remainder num 2) 0)))


(define fibonacci-filtered-range
  (lambda* (start
            end
            #:key
            [fib-init (cons 1 1)]
            [predicate (λ (n) #t)])
    (let iter ([prev-prev (car fib-init)] [prev (cdr fib-init)])
      (cond
       ;; First check for the stopping condition.
       [(>= prev end)
        (if (predicate prev-prev)
            (list prev-prev)
            '())]
       [(>= prev-prev start)
        (if (predicate prev-prev)
            (cons prev-prev
                  (iter prev (+ prev-prev prev)))
            (iter prev (+ prev-prev prev)))]
       [else
        (iter prev (+ prev-prev prev))]))))



(simple-format
 (current-output-port)
 "~a\n"
 (sum
  (fibonacci-filtered-range 0
                            (* 4 (expt 10 6))
                            #:fib-init (cons 1 2)
                            #:predicate even?)))  ; 4613732
